﻿using System;
using System.Diagnostics.Contracts;
using Wombat.Core.Services;

namespace Wombat.Core.Factories
{
    public class TagValueFactory : ITagValueFactory
    {
        private readonly ITagRpository _tagRpository;
        private readonly ISpecialValueFactory _specialValueFactory;

        private Exception DataTypeNotSupportedException(ITag tag)
        {
            return new InvalidOperationException(string.Format("Data type '{0}' is not supported", tag.DataType));
        }

        public TagValueFactory(ITagRpository tagRpository, ISpecialValueFactory specialValueFactory)
        {
            _tagRpository = tagRpository;
            _specialValueFactory = specialValueFactory;
        }

        public ITagValue CreateNew(Guid tagId, DateTime time, object value)
        {
            Contract.Assert(tagId != null && tagId != Guid.Empty);

            var tag = _tagRpository.Get(tagId);
            if (tag.DataType == typeof (double?))
            {
                return CreateNew(tagId, time, value == null ? (double?)null : Convert.ToDouble(value));
            }
            throw DataTypeNotSupportedException(tag);
        }

        public ITagValue<T> CreateNew<T>(Guid tagId, DateTime time, T value)
        {
            return new TagValue<T> {TagId = tagId, Time = time, Value = value};
        }

        public ITagValue<T> CreateCurropt<T>(Guid tagId, DateTime time)
        {
            return CreateNew(tagId, time, (T)_specialValueFactory.GetCorruptValue(typeof(T)));
        }

        public ITagValue CreateCurropt(Guid tagId, DateTime time)
        {
            Contract.Assert(tagId != null && tagId != Guid.Empty);

            var tag = _tagRpository.Get(tagId);
            if (tag.DataType == typeof (double?))
            {
                CreateCurropt<double?>(tagId, time);
            }
            throw DataTypeNotSupportedException(tag);
        }
    }
}